home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
050
/
mothello.arc
/
MOTHELLO.PAS
Wrap
Pascal/Delphi Source File
|
1987-01-26
|
13KB
|
438 lines
{ Name: OTHELLO.PAS }
{ Programmer: Calvin A. Jones }
{ Date written: 11/24/84 }
{ Description: Original PET version modified FOR Turbo Pascal }
{ under MS-DOS. }
{ Updated: July 24, 1985 Phil Glatz }
{ MicroSoft mouse support added, Turbo 3.0 upgrade }
PROGRAM Othello;
{$V-}
CONST
fff = green;
bbb = black;
c: ARRAY[1..2] OF INTEGER = (blue,red);
i4: ARRAY[0..7] OF INTEGER = (-1, 0, 1,1,1,0,-1,-1);
j4: ARRAY[0..7] OF INTEGER = (-1,-1,-1,0,1,1, 1, 0);
TYPE
charset = set OF CHAR;
ArgString = STRING[255] ;
VAR
ch: CHAR;
sc: ARRAY[1..2] OF INTEGER;
a: ARRAY[0..9,0..9] OF INTEGER;
player: ARRAY[1..2] OF string[15];
n1,np,op,pt,s1,s2,s3,s4,s5: INTEGER;
Passing : BOOLEAN ;
MouseX, MouseY,
xl,xh,yl,yh: INTEGER;
done,over: BOOLEAN;
{$I c:\turbo\inc\mouse.inc }
procedure getchar(VAR ch: CHAR; range: charset);
BEGIN
REPEAT
read(kbd,ch);
IF ch=#27 THEN Begin TextMode ; halt end ;
ch:=upcase(ch);
UNTIL ch in range;
END;
procedure score;
VAR
i,j: INTEGER;
BEGIN
window(1,1,40,20);
textbackground(cyan);
FOR i:=1 to 8 do
FOR j:=1 to 8 do
IF a[i,j]<>0 THEN
BEGIN
textcolor(c[a[i,j]]);
GotoXY(4*i+1,2*j+3); WRITE(chr(a[i,j]));
END;
textcolor(c[1]);
GotoXY(38,5); WRITE(sc[1]:2);
textcolor(c[2]);
GotoXY(38,19); WRITE(sc[2]:2);
textcolor(fff); textbackground(bbb);
IF (sc[op]=0) or (n1=64) THEN
BEGIN
window(1,21,40,24);
clrscr;
WriteLn(player[1],' has ',sc[1],' pieces');
WriteLn(player[2],' has ',sc[2],' pieces');
IF sc[1]=sc[2] THEN WriteLn('It is a tie !!')
ELSE
BEGIN
IF sc[1]>sc[2] THEN WRITE(player[1]) ELSE WRITE(player[2]);
WriteLn(' won !!!');
END;
over:=TRUE;
WRITE('Do you want to play again? ');
getchar(ch,['Y','N']);
IF (ch)='N' THEN done:=TRUE;
END;
END;
procedure intro;
VAR
i : INTEGER ;
BEGIN
textmode(c40);
textcolor(black); textbackground(black);
ClrScr ;
textcolor(white); textbackground(cyan);
GotoXY(19,5); WRITE('IBM');
GotoXY(12,7); WRITE('Personal Computer');
GotoXY(8,10); WRITE('╒═══════════════════════╕');
GotoXY(8,11); WRITE('│ -*- OTHELLO -*- │');
GotoXY(8,12); WRITE('│ │');
GotoXY(8,13); WRITE('│ Author: Unkown │');
GotoXY(8,14); WRITE('│ Adapted by: P. Leabo │');
GotoXY(8,15); WRITE('│Enhanced by: R. Vollmer│');
GotoXY(8,16); WRITE('│Pacsal Ver.: C. Jones │');
GotoXY(8,16); WRITE('│ Mouse Ver.: P. Glatz │');
GotoXY(8,17); WRITE('╘═══════════════════════╛');
GotoXY(5,20); WRITE('Orig. written FOR: PET computer');
GotoXY(10,21); WRITE('Last update: 07/24/85');
i := 0 ;
WHILE (NOT KeyPressed) AND (i < 50) DO (* delay until key pressed or 5 sec *)
BEGIN
Delay(100) ;
i := Succ(i)
END
END;
procedure instructions;
BEGIN
textmode(c80);
textcolor(7); textbackground(1);
clrscr;
window(10,1,70,24);
GotoXY(20,4); WriteLn('GREETINGS FROM OTHELLO');
WriteLn;
WriteLn('Othello is played on an 8 x 8 board, rows numbered 1 to 8');
WriteLn('and columns numbered A to H. The initial configuration is');
WriteLn('all blank except FOR the four center squares. Try to place');
WriteLn('your pieces so that it outflanks your opponent, creating');
WriteLn('horizontal, vertical, or diagonal runs of opposing pieces,');
WriteLn('turning them into yours.');
WriteLn;
WriteLn('Make your move by pointing to the square you wish and press');
WriteLn('mouse button # 1.');
WriteLn;
WriteLn('Note: You must capture at least one OF your opponent''s');
WriteLn('pieces. If it is not possible, you forfeit your move by');
WriteLn('pointing at Pass.');
WriteLn('Point at Quit to abort the game');
WriteLn('You may also specify whether you are player 1 or 2 by typing');
WriteLn('MOTHELLO n, (where n is 1 or 2) on the command line. This');
WriteLn('will also skip this instruction screen.') ;
WriteLn; WriteLn;
WRITE('Press any key to continue...'); read(kbd,ch);
END;
procedure initialize;
VAR
i,j: INTEGER;
Arg : String[1] ;
PROCEDURE GetAnswers ;
BEGIN
WRITE('How many players? (1 or 2) ');
getchar(ch,['1','2']); WriteLn(ch);
np:=ord(ch)-ord('0');
WriteLn;
WRITE('Player 1''s name: '); readln(player[1]);
IF np=2 THEN
BEGIN
WRITE('Player 2''s name: '); readln(player[2]);
END;
IF np<>2 THEN
BEGIN
player[2]:='Computer';
WriteLn; WRITE('Should I play my best? ');
getchar(ch,['Y','N']);
IF ch='Y' THEN
BEGIN
WriteLn('YES');
s2:=2; s4:=1; s5:=-2;
END
ELSE
BEGIN
WriteLn('NO');
s2:=0; s4:=0; s5:=0;
END;
END;
END ; (* Procedure GetAnswers *)
BEGIN
window(1,1,80,24);
textmode(c40);
done:=FALSE; over:=FALSE;
xl:=3; xh:=6;
yl:=3; yh:=6;
IF ParamCount = 0 THEN
GetAnswers
ELSE
BEGIN
np := 1 ;
player[1] := '' ;
player[2] := '' ;
Arg := (ParamStr(1)) ;
IF (Arg[1] IN ['1'..'2']) THEN np:=ord(Arg[1])-ord('0')
ELSE np := 1 ;
s2:=0; s4:=0; s5:=0
END ;
FOR i:=0 to 9 do
FOR j:=0 to 9 do a[i,j]:=0;
a[4,4]:=1; a[4,5]:=2;
a[5,4]:=2; a[5,5]:=1;
n1:=4;
op:=1;
FOR i:=1 to 2 do sc[i]:=2;
END;
procedure draw_board;
BEGIN
clrscr;
textcolor(magenta); textbackground(blue);
GotoXY(5,1); WriteLn('O T H E L L O');
textcolor(LightGray);
GotoXY(30,1); WriteLn('Pass Quit');
GotoXY(1,3);
textcolor(brown); textbackground(lightgray);
WriteLn(' 1 2 3 4 5 6 7 8 ');
WriteLn(' ╔═══╦═══╦═══╦═══╦═══╦═══╦═══╦═══╗');
WriteLn('A ║ ║ ║ ║ ║ ║ ║ ║ ║');
WriteLn(' ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣');
WriteLn('B ║ ║ ║ ║ ║ ║ ║ ║ ║');
WriteLn(' ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣');
WriteLn('C ║ ║ ║ ║ ║ ║ ║ ║ ║');
WriteLn(' ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣');
WriteLn('D ║ ║ ║ ║ ║ ║ ║ ║ ║');
WriteLn(' ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣');
WriteLn('E ║ ║ ║ ║ ║ ║ ║ ║ ║');
WriteLn(' ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣');
WriteLn('F ║ ║ ║ ║ ║ ║ ║ ║ ║');
WriteLn(' ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣');
WriteLn('G ║ ║ ║ ║ ║ ║ ║ ║ ║');
WriteLn(' ╠═══╬═══╬═══╬═══╬═══╬═══╬═══╬═══╣');
WriteLn('H ║ ║ ║ ║ ║ ║ ║ ║ ║');
WriteLn(' ╚═══╩═══╩═══╩═══╩═══╩═══╩═══╩═══╝');
textcolor(blue);
GotoXY(36,5); WRITE(chr(1));
textcolor(red);
GotoXY(36,19); WRITE(chr(2));
score;
END;
function test_move(x,y: INTEGER): BOOLEAN;
VAR i,j: INTEGER;
BEGIN
test_move:=FALSE;
FOR i:=-1 to 1 do
FOR j:=-1 to 1 do
IF a[x+i,y+j]=op THEN test_move:=TRUE;
END;
procedure count_flank(x,y,z: INTEGER);
VAR i5,j5,i6,j6,k,k1: INTEGER;
BEGIN
s1:=0; k:=0;
while k<8 do
BEGIN
s3:=0;
i5:=i4[k]; j5:=j4[k]; i6:=x+i5; j6:=y+j5;
IF a[i6,j6]=op THEN
BEGIN
REPEAT
s3:=s3+1;
i6:=i6+i5; j6:=j6+j5;
UNTIL (a[i6,j6]=0) or (a[i6,j6]=pt);
IF a[i6,j6]=pt THEN
BEGIN
s1:=s1+s3;
IF z=1 THEN
BEGIN
i6:=x; j6:=y;
FOR k1:=0 to s3 do
BEGIN
a[i6,j6]:=pt;
i6:=i6+i5; j6:=j6+j5;
END;
END;
END;
END;
k:=k+1;
END;
END;
procedure show_move(x,y: INTEGER);
BEGIN
window(1,1,40,20);
GotoXY(4*x+1,2*y+3);
textcolor(c[pt]+blink); textbackground(lightgray);
WRITE(chr(pt));
textcolor(fff); textbackground(bbb);
delay(2500);
window(1,21,40,24);
GotoXY(1,1);
count_flank(x,y,1);
sc[pt]:=sc[pt]+s1+1;
sc[op]:=sc[op]-s1;
n1:=n1+1;
END;
procedure computer_move;
VAR i,j,b1,i3,j3: INTEGER;
BEGIN
window(1,21,40,25);
clrscr;
IF Passing THEN WriteLn('Passing...') ELSE WriteLn;
textcolor(fff+blink);
WriteLn('I am thinking!');
textcolor(fff);
b1:=-1; i3:=0; j3:=0;
FOR i:=xl to xh do
FOR j:=yl to yh do
IF a[i,j]=0 THEN
IF test_move(i,j) THEN
BEGIN
count_flank(i,j,0);
IF s1>0 THEN
BEGIN
IF (i=1) or (i=8) THEN s1:=s1+s2;
IF (j=1) or (j=8) THEN s1:=s1+s2;
IF (i=2) or (i=7) THEN s1:=s1+s5;
IF (j=2) or (j=7) THEN s1:=s1+s5;
IF (i=3) or (i=6) THEN s1:=s1+s4;
IF (j=3) or (j=6) THEN s1:=s1+s4;
IF s1>=b1 THEN
IF (s1>b1) or (random(1)>0.5) THEN
BEGIN
b1:=s1; i3:=i; j3:=j;
END;
END;
END;
IF (i3 in [1..8]) and (j3 in [1..8]) THEN
BEGIN
i:=i3; j:=j3;
show_move(i,j);
IF (i<=xl) and (i<>1) THEN xl:=xl-1;
IF (i>=xh) and (i<>8) THEN xh:=xh+1;
IF (j<=yl) and (j<>1) THEN yl:=yl-1;
IF (j>=yh) and (j<>8) THEN yh:=yh+1;
END
ELSE WriteLn('Computer passes.');
delay(2500);
END;
procedure player_move;
CONST
term: charset = ['1'..'8','A'..'H',^M];
VAR
d,i,j: INTEGER;
goodmove: BOOLEAN;
BEGIN
window(1,21,40,25);
clrscr;
WriteLn;
goodmove:=FALSE;
Passing := FALSE ;
over := FALSE ;
REPEAT
WRITE(player[pt],' ');
textcolor(c[pt]); WRITE(chr(pt));
textcolor(fff); WRITE(', enter your move: ');
i:=-1; j:=-1;
REPEAT
IF (MousePosition(MouseX, MouseY) = 1) THEN
IF (MouseY = 0) THEN
CASE MouseX OF
464..512 : Passing := TRUE ;
576..624 : BEGIN
goodmove := TRUE ;
done := TRUE ;
over := TRUE
END
ELSE END (* CASE *)
ELSE
BEGIN
i := ((MouseX-64) DIV 64) + 1 ;
j := ((MouseY-32) DIV 16) + 1 ;
Sound(500) ;
Delay(2) ;
Sound(300) ;
Delay(3) ;
NoSound ;
Delay(250) (* pause to eliminate bounce *)
END (* IF *)
UNTIL ((i>0) and (j>0)) OR Passing OR over ;
IF Passing THEN
BEGIN
FOR d := 300 TO 1950 DO Sound(d) ;
Delay(5) ;
NoSound ;
Delay(200) ;
goodmove:=TRUE
END
ELSE IF (NOT over) THEN
BEGIN
IF a[i,j]=0 THEN
BEGIN
IF test_move(i,j) THEN
BEGIN
count_flank(i,j,0);
IF s1>0 THEN
BEGIN
goodmove:=TRUE;
show_move(i,j);
END
ELSE WriteLn('Sorry, does not flank a row.')
END
ELSE WriteLn('Sorry, not next to opponents pieces.')
END
ELSE WriteLn('Sorry, square occupied; try again.');
END; (* PlayerMove *)
UNTIL goodmove;
END;
BEGIN
intro;
IF ParamCount = 0 THEN instructions;
REPEAT
initialize;
InstallMouse ;
draw_board;
SetTextCursor(TRUE,1,5) ;
ShowMouse ;
REPEAT
pt:=1; op:=2;
player_move;
score;
IF not over THEN
BEGIN
pt:=2; op:=1;
IF np=2 THEN player_move ELSE computer_move;
score;
END;
UNTIL over;
UNTIL done;
NoSound ;
QuitMouse ;
window(1,1,80,24);
textmode(c80);
END.